/*
 * Copyright 2013 Sigurd Randoll <srandoll@digiway.de>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.digiway.rapidbreeze.server.infrastructure.rest.config;

import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.core.ClassNamesResourceConfig;
import com.sun.jersey.spi.container.servlet.WebComponent;
import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
import com.sun.jersey.test.framework.AppDescriptor;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.WebAppDescriptor;
import de.digiway.rapidbreeze.server.model.config.ConfigurationRepository;
import de.digiway.rapidbreeze.shared.rest.ResourceLocation;
import de.digiway.rapidbreeze.shared.rest.config.ServerConfigurationResourceEntry;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import org.junit.Test;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
import org.junit.Before;

/**
 *
 * @author Sigurd Randoll <srandoll@digiway.de>
 */
public class ServerConfigurationResourceIT extends JerseyTest {

    private static ConfigurationRepository configurationRepository = mock(ConfigurationRepository.class);
    private static final String KEY_1 = "key1";
    private static final String KEY_2 = "key2";
    private static final String VALUE_1 = "value1";
    private static final String VALUE_2 = "value2";

    @Override
    protected AppDescriptor configure() {
        return new WebAppDescriptor.Builder().
                initParam(WebComponent.RESOURCE_CONFIG_CLASS, ClassNamesResourceConfig.class.getName()).
                initParam(ClassNamesResourceConfig.PROPERTY_CLASSNAMES, ServerConfigurationResource.class.getName() + ";" + ServerConfigurationResourceEntry.class.getName() + ";" + MockConfigurationRepositoryProvider.class.getName()).
                build();
    }

    @Before
    public void setup() {
        Map<String, Object> map = new HashMap<>();
        map.put(KEY_1, VALUE_1);
        map.put(KEY_2, VALUE_2);
        when(configurationRepository.getAllConfigurations()).thenReturn(map);
        when(configurationRepository.getValue(KEY_1)).thenReturn(VALUE_1);
        when(configurationRepository.getValue(KEY_2)).thenReturn(VALUE_2);
    }

    @Test
    public void testGetAllConfigurations() throws MalformedURLException, IOException {
        WebResource webResource = resource();
        GenericType<List<ServerConfigurationResourceEntry>> genericType = new GenericType<List<ServerConfigurationResourceEntry>>() {
        };
        Collection<ServerConfigurationResourceEntry> get = webResource.path(ResourceLocation.SERVER_CONFIGURATION_RESOURCE_PATH).type(MediaType.APPLICATION_XML).get(genericType);
        assertEquals(2, get.size());

        // First resource:
        Iterator<ServerConfigurationResourceEntry> it = get.iterator();
        ServerConfigurationResourceEntry res1 = it.next();
        assertEquals(KEY_2, res1.getKey());
        assertEquals(VALUE_2, res1.getValue());

        // 2nd resource:
        ServerConfigurationResourceEntry res2 = it.next();
        assertEquals(KEY_1, res2.getKey());
        assertEquals(VALUE_1, res2.getValue());
    }

    @Test
    public void testGetConfiguration() throws MalformedURLException, IOException {
        WebResource webResource = resource();
        ServerConfigurationResourceEntry resource = webResource.path(ResourceLocation.SERVER_CONFIGURATION_RESOURCE_PATH + "/" + KEY_1).type(MediaType.APPLICATION_XML).get(ServerConfigurationResourceEntry.class);
        assertEquals(KEY_1, resource.getKey());
        assertEquals(VALUE_1, resource.getValue());

        resource = webResource.path(ResourceLocation.SERVER_CONFIGURATION_RESOURCE_PATH + "/" + KEY_2).type(MediaType.APPLICATION_XML).get(ServerConfigurationResourceEntry.class);
        assertEquals(KEY_2, resource.getKey());
        assertEquals(VALUE_2, resource.getValue());

        // Not found:
        ClientResponse response = webResource.path(ResourceLocation.SERVER_CONFIGURATION_RESOURCE_PATH + "/non-existing").type(MediaType.APPLICATION_XML).get(ClientResponse.class);
        assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
    }

    public static class MockConfigurationRepositoryProvider extends SingletonTypeInjectableProvider<Context, ConfigurationRepository> {

        public MockConfigurationRepositoryProvider() {
            super(ConfigurationRepository.class, configurationRepository);
        }
    }
}
